﻿using System;
using System.Text;
using System.Web.Mvc;
using Flagwind.Resources;
using Flagwind.Runtime.Serialization;

namespace Flagwind.Web
{
	/// <summary>
	/// 表示一个以 JSON 格式为载体的响应类。
	/// </summary>
	public class JsonResult : ActionResult
	{
		#region 公共属性

		/// <summary>
		/// 获取或设置 HTTP 状态码。
		/// </summary>
		public int? HttpCode
		{
			get;
			set;
		}

		/// <summary>
		/// 获取或设置内容编码。
		/// </summary>
		public Encoding ContentEncoding
		{
			get;
			set;
		}

		/// <summary>
		/// 获取或设置需要序列化的内容。
		/// </summary>
		public virtual object Data
		{
			get;
			set;
		}

		/// <summary>
		/// 获取或设置是否允许来自客户端的 HTTP GET 请求。
		/// </summary>
		public JsonRequestBehavior JsonRequestBehavior
		{
			get;
			set;
		}

		/// <summary>
		/// 获取或设置 MIME 类型。
		/// </summary>
		public string ContentType
		{
			get;
			set;
		}

		/// <summary>
		/// 获取或者设置序列化器配置。
		/// </summary>
		public TextSerializationSettings SerializerSettings
		{
			get;
			set;
		}

		#endregion

		#region 构造方法

		/// <summary>
		/// 初始化 JsonResult 类的新实例。
		/// </summary>
		public JsonResult() : this(null, null)
		{

		}

		/// <summary>
		/// 初始化 JsonResult 类的新实例。
		/// </summary>
		/// <param name="data">待序列化的数据。</param>
		public JsonResult(object data) : this(data, null)
		{
		}

		/// <summary>
		/// 初始化 JsonResult 类的新实例。
		/// </summary>
		/// <param name="data">待序列化的数据。</param>
		/// <param name="settings"></param>
		public JsonResult(object data, TextSerializationSettings settings)
		{
			this.Data = data;
			this.JsonRequestBehavior = JsonRequestBehavior.AllowGet;
			this.SerializerSettings = settings ?? TextSerializationSettings.Default;
		}

		#endregion

		#region 重写方法

		public override void ExecuteResult(ControllerContext context)
		{
			if(context == null)
				throw new ArgumentNullException("context");

			if(JsonRequestBehavior == JsonRequestBehavior.DenyGet && string.Equals(context.HttpContext.Request.HttpMethod, "GET", StringComparison.OrdinalIgnoreCase))
				throw new InvalidOperationException(ResourceUtility.GetString("${Text.JsonRequest.GetNotAllowed}"));

			var response = context.HttpContext.Response;

			// 设置 HTTP 状态码
			if(this.HttpCode != null)
				response.StatusCode = this.HttpCode.Value;

			// 设置响应类型
			response.ContentType = string.IsNullOrEmpty(this.ContentType) ? "application/json" : this.ContentType;

			// 设置响应编码
			if(this.ContentEncoding != null)
				response.ContentEncoding = this.ContentEncoding;

			// 如果内容为空，则跳过处理
			if(this.Data == null)
				return;

			// 序列化响应内容
			var responseText = Serializer.Json.Serialize(this.Data, this.SerializerSettings);

			// 输出响应内容
			response.Write(responseText);
		}

		#endregion
	}
}
